package com.tools.middle.elasticsearch;

import com.tools.common.container.OwnPairs;
import com.tools.common.object.C;
import com.tools.common.object.Note;
import com.tools.common.object.ObjKit;
import com.tools.common.object.string.VerifyKit;
import com.tools.common.thread.Timeunit;

import java.util.Map;

/**
 * 文档操作时所需的参数包装实体
 * */
@Note("文档操作时所需的参数包装实体")
public class ESDocBuilder {

    @Note("索引名称")
    private String indicesName;

    @Note("文档 ID")
    private String id;

    @Note("文档实体")
    private Object document;

    @Note("超时时间，默认 1 秒")
    private String timeout = "1s";

    @Note("只有是批量操作请求时才需要初始化的值。" +
            "代表的是该次批处理，this 文档是什么操作")
    private ESDocBulkOpEnum bulkOpEnum;

    /* ***********************************************************************************
     *
     *         构造器
     *
     * **********************************************************************************
     * */

    public ESDocBuilder(String indicesName, String id, Object document) {
        this.setIndicesName(indicesName);
        this.setId(id);
        this.document = document;
    }

    public static ESDocBuilder of(String indicesName, String id, Object document) {
        return new ESDocBuilder(indicesName, id, document);
    }

    /* ***********************************************************************************
     *
     *         Getter / Setter
     *
     * **********************************************************************************
     * */

    public static ESDocBuilder build(String indicesName, String id, Object document) {
        return new ESDocBuilder(indicesName, id, document);
    }

    public String getIndicesName() {
        return indicesName;
    }

    public void setIndicesName(String indicesName) {
        if(indicesName == null || indicesName.isEmpty()) throw new NullPointerException("索引名称为空");
        this.indicesName = indicesName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        if(id == null || id.isEmpty()) throw new NullPointerException("文档 ID 为空");
        this.id = id;
    }

    public void setId(long id) {
        this.id = String.valueOf(id);
    }

    public Object getDocument() {
        return document;
    }

    public <T>T getDocument(Class<T> documentType) {
        return (T) document;
    }

    public <T>T getDocument(C<T> documentType) {
        return (T) ObjKit.toRealValue(document, documentType);
    }

    public void setDocument(Object javaBean) {
        if(javaBean == null) throw new NullPointerException("文档实体不能为 null");
        this.document = javaBean;
    }

    public void setDocument(String jsonObject) {
        if(!VerifyKit.isJsonObject(jsonObject)) throw new IllegalArgumentException("\n" + jsonObject + "\n 不是对象类型的 JSON 字符串");
        this.document = jsonObject;
    }

    public void setDocument(Map document) {
        if(document == null || document.isEmpty()) throw new NullPointerException("文档实体不能为空");
        this.document = document;
    }

    public void setDocument(OwnPairs document) {
        if(document == null || document.isEmpty()) throw new NullPointerException("文档实体不能为空");
        this.document = document;
    }

    public String getTimeout() {
        return timeout;
    }

    public void setTimeout(String timeout) {
        if(timeout == null || timeout.isEmpty()) return;
        this.timeout = timeout;
    }

    public void setTimeout(long timeout, Timeunit timeunit) {
        if(timeunit == null) throw new NullPointerException("超时时间单位枚举实例为 null");
        this.timeout = timeunit.getHasUnitTime(timeout);
    }

    public ESDocBulkOpEnum getBulkOpEnum() {
        return bulkOpEnum;
    }

    public void setBulkOpEnum(ESDocBulkOpEnum bulkOpEnum) {
        this.bulkOpEnum = bulkOpEnum;
    }

    @Override
    public String toString() {
        return "ESDocBuilder{" +
                "indicesName='" + indicesName + '\'' +
                ", id='" + id + '\'' +
                ", document=" + document +
                ", timeout='" + timeout + '\'' +
                ", bulkOpEnum=" + bulkOpEnum +
                '}';
    }

    /* ***********************************************************************************
     *
     *         链式方法
     *
     * **********************************************************************************
     * */

    public ESDocBuilder indicesName(String indicesName) {
        this.setIndicesName(indicesName);
        return this;
    }

    public ESDocBuilder id(String id) {
        this.setId(id);
        return this;
    }

    public ESDocBuilder id(long id) {
        this.setId(id);
        return this;
    }

    public ESDocBuilder document(Object javaBean) {
        this.setDocument(javaBean);
        return this;
    }

    public ESDocBuilder document(String jsonObject) {
        this.setDocument(jsonObject);
        return this;
    }

    public ESDocBuilder document(Map document) {
        this.setDocument(document);
        return this;
    }

    public ESDocBuilder document(OwnPairs document) {
        this.setDocument(document);
        return this;
    }

    public ESDocBuilder timeout(String timeout) {
        this.setTimeout(timeout);
        return this;
    }

    public ESDocBuilder timeout(long timeout, Timeunit timeunit) {
        this.setTimeout(timeout, timeunit);
        return this;
    }

    public ESDocBuilder bulkOpEnum(ESDocBulkOpEnum bulkOpEnum) {
        this.setBulkOpEnum(bulkOpEnum);
        return this;
    }
}
